<?php
class FileUtil {
	
	/**
     * Return a context-relative path, beginning with a "/", that represents
     * the canonical version of the specified path after ".." and "." elements
     * are resolved out.  If the specified path attempts to go outside the
     * boundaries of the current context (i.e. too many ".." path elements
     * are present), return <code>null</code> instead.
     *
     * @param string $path Path to be normalized
     * @return string normalized path
     */
    public static function normalizePath($path)
    {
        // Normalize the slashes and add leading slash if necessary
        $normalized = $path;
        if (strpos($normalized, '\\') !== false)
        {
            $normalized = str_replace('\\', '/', $normalized);
        }
        
        if (! substr($normalized, 0, 1) == '/') {
        	$normalized = '/' . $normalized;
        }
        
        // Resolve occurrences of "//" in the normalized path
        while (true)
        {
        	$index = strpos($normalized, "//");
        	
            if ($index === false)
                break;
                
            $normalized = substr($normalized, 0, $index) . substr($normalized, $index + 1);
        }
        
        // Resolve occurrences of "%20" in the normalized path
        $normalized = str_replace("%20", " ", $normalized);

        // Resolve occurrences of "/./" in the normalized path
        $normalized = str_replace("/./", "/", $normalized);
        
        // Resolve occurrences of "/../" in the normalized path
        while (true)
        {
            $index = strpos($normalized, "/../");
            
            if ($index === false)
                break;
                
            if ($index == 0)
                return (null);  // Trying to go outside our context
                
            $index2 = strpos($normalized, '/', $index - 1);
            $normalized = substr($normalized, 0, $index2) .
            	substr($normalized, $index + 3);
        }

        // Return the normalized path that we have completed
        return $normalized;
    }
}
?>